/*
 * Copyright (C) 2021      Andy Nguyen
 * Copyright (C) 2021      Rinnegatamante
 * Copyright (C) 2022-2024 Volodymyr Atamanenko
 *
 * This software may be modified and distributed under the terms
 * of the MIT license. See the LICENSE file for details.
 */

/**
 * @file  dynlib.c
 * @brief Resolving dynamic imports of the .so.
 */

#include <psp2/kernel/clib.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <inttypes.h>
#include <malloc.h>
#include <math.h>
#include <netdb.h>
#include <string.h>
#include <wchar.h>
#include <wctype.h>
#include <zlib.h>
#include <locale.h>
#include <poll.h>

#include <sys/stat.h>
#include <sys/unistd.h>
#include <sys/socket.h>
#include <sys/time.h>

#include <so_util/so_util.h>
#include <utime.h>

#include "utils/glutil.h"
#include "utils/utils.h"
#include "utils/logger.h"

#include <png.h>
#include <pngconf.h>
#include <pnglibconf.h>
#include <zconf.h>
#include <jerror.h>

#ifdef USE_SCELIBC_IO
#include <libc_bridge/libc_bridge.h>
#endif

#include "reimpl/errno.h"
#include "reimpl/io.h"
#include "reimpl/log.h"
#include "reimpl/mem.h"
#include "reimpl/pthr.h"
#include "reimpl/sys.h"
#include "reimpl/egl.h"
#include "reimpl/time64.h"
#include "reimpl/asset_manager.h"
#include "reimpl/md5.h"
#include "reimpl/android/String8.h"
#include "reimpl/android7string8.h"
#include "reimpl/android/SharedBuffer.h"

const unsigned int __page_size = PAGE_SIZE;

// RefBase 的简化实现
typedef struct
{
    int strong_refs;
    int weak_refs;
    void *extensions;
} RefBaseImpl;

// RefBase 构造函数
void _ZN7android7RefBaseC2Ev(void *self)
{
    l_debug("_ZN7android7RefBaseC2Ev: %p", self);
    //    RefBaseImpl* ref = (RefBaseImpl*)self;
    //    ref->strong_refs = 0;
    //    ref->weak_refs = 0;
    //    ref->extensions = NULL;
}

// RefBase 析构函数
void _ZN7android7RefBaseD2Ev(void *self)
{
    l_debug("_ZN7android7RefBaseD2Ev: %p", self);
    //    RefBaseImpl* ref = (RefBaseImpl*)self;
    //    if (ref->extensions) {
    //        free(ref->extensions);
    //    }
}

void _ZN7android7RefBase10onFirstRefEv(void *self)
{
    l_debug("_ZN7android7RefBase10onFirstRefEv: %p", self);
}

void _ZN7android7RefBase15onLastStrongRefEPKv(void *self, const void *id)
{
    l_debug("_ZN7android7RefBase15onLastStrongRefEPKv: %p, id = %d", self, id);
}

void _ZN7android7RefBase13onLastWeakRefEPKv(void *self, const void *id)
{
    l_debug("_ZN7android7RefBase13onLastWeakRefEPKv: %p, id = %d", self, id);
}

int _ZN7android7RefBase20onIncStrongAttemptedEjPKv(void *self, unsigned int flags, const void *id)
{
    l_debug("_ZN7android7RefBase20onIncStrongAttemptedEjPKv: %p, flags = %d, id = %d", self, flags, id);
    return 1;
}

// Thread 类的完全空实现
void _ZN7android6ThreadC2Eb(void *self, int canCallJava)
{
    l_debug("[Thread] Constructor (EMPTY): %p, canCallJava: %d", self, canCallJava);
}

void _ZN7android6ThreadD0Ev(void *self)
{
    l_debug("[Thread] D0 destructor (EMPTY): %p", self);
}

void _ZN7android6ThreadD1Ev(void *self)
{
    l_debug("[Thread] D1 destructor (EMPTY): %p", self);
}

void _ZN7android6ThreadD2Ev(void *self)
{
    l_debug("[Thread] D2 destructor (EMPTY): %p", self);
}

int _ZN7android6Thread10readyToRunEv(void *self)
{
    l_debug("[Thread] readyToRun (EMPTY): %p", self);
    return 1;
}

void _ZN7android6Thread11requestExitEv(void *self)
{
    l_debug("[Thread] requestExit (EMPTY): %p", self);
}

int _ZN7android6Thread3runEPKcij(void *self, const char *name, int priority, size_t stack)
{
    l_debug("[Thread] run (EMPTY): %p, name: %s, priority: %d, stack: %zu",
            self, name ? name : "NULL", priority, stack);
    return 1;
}

typedef struct
{
    int ref_count; // 简单的引用计数
} SimpleRefBase;

void _ZNK7android7RefBase9incStrongEPKv(void *self, const void *id)
{
    SimpleRefBase *ref = (SimpleRefBase *)self;
    ref->ref_count++;
    l_debug("[RefBase] incStrong: %p -> count=%d", self, ref->ref_count);
}

void _ZNK7android7RefBase9decStrongEPKv(void *self, const void *id)
{
    SimpleRefBase *ref = (SimpleRefBase *)self;
    ref->ref_count--;
    l_debug("[RefBase] decStrong: %p -> count=%d", self, ref->ref_count);
}

int chdir_wrap(const char *__path)
{
    l_debug("chdir invoke %s", __path);
    // return chdir(__path);
    return chdir(DATA_PATH);
}

// additional aeabi extern
extern void *__aeabi_i2f;
extern void *__aeabi_fmul;
extern void *__aeabi_f2iz;

extern void *_ZNSt9exceptionD2Ev;
extern void *_ZSt17__throw_bad_allocv;
extern void *_ZSt9terminatev;
extern void *_ZdaPv;
extern void *_ZdlPv;
extern void *_Znaj;
extern void *__cxa_allocate_exception;
extern void *__cxa_begin_catch;
extern void *__cxa_end_catch;
extern void *__cxa_free_exception;
extern void *__cxa_rethrow;
extern void *__cxa_throw;
extern void *__gxx_personality_v0;
extern void *_ZNSt8bad_castD1Ev;
extern void *_ZTISt8bad_cast;
extern void *_ZTISt9exception;
extern void *_ZTVN10__cxxabiv117__class_type_infoE;
extern void *_ZTVN10__cxxabiv120__si_class_type_infoE;
extern void *_ZTVN10__cxxabiv121__vmi_class_type_infoE;
extern void *_Znwj;
extern void *__aeabi_atexit;
extern void *__aeabi_d2lz;
extern void *__aeabi_d2ulz;
extern void *__aeabi_dadd;
extern void *__aeabi_dcmpgt;
extern void *__aeabi_dcmplt;
extern void *__aeabi_ddiv;
extern void *__aeabi_dmul;
extern void *__aeabi_f2lz;
extern void *__aeabi_f2ulz;
extern void *__aeabi_i2d;
extern void *__aeabi_idiv;
extern void *__aeabi_idivmod;
extern void *__aeabi_l2d;
extern void *__aeabi_l2f;
extern void *__aeabi_ldivmod;
extern void *__aeabi_memclr;
extern void *__aeabi_memcpy;
extern void *__aeabi_memmove;
extern void *__aeabi_memset4;
extern void *__aeabi_memset8;
extern void *__aeabi_memset;
extern void *__aeabi_ui2d;
extern void *__aeabi_uidiv;
extern void *__aeabi_uidivmod;
extern void *__aeabi_ul2d;
extern void *__aeabi_ul2f;
extern void *__aeabi_uldivmod;
extern void *__aeabi_unwind_cpp_pr0;
extern void *__aeabi_unwind_cpp_pr1;
extern void *__cxa_atexit;
extern void *__cxa_call_unexpected;
extern void *__cxa_finalize;
extern void *__cxa_guard_acquire;
extern void *__cxa_guard_release;
extern void *__cxa_pure_virtual;
extern void *__gnu_ldivmod_helper;
extern void *__gnu_unwind_frame;
extern void *__srget;
extern void *__stack_chk_guard;
extern void *__swbuf;

extern void *__aeabi_llsl;

extern const char *BIONIC_ctype_;
extern const short *BIONIC_tolower_tab_;
extern const short *BIONIC_toupper_tab_;

static FILE __sF_fake[3];
so_default_dynlib *default_dynlib_m;
int size_default_dynlib;
void *dlsym_soloader(void *handle, const char *symbol)
{
    // Usage example:
    // if (strcmp("AMotionEvent_getAxisValue", symbol) == 0)
    //    return &AMotionEvent_getAxisValue;

    int size_default_dynlib_type = sizeof(so_default_dynlib);
    void *result = NULL;
    uintptr_t val;
    for (int j = 0; j < size_default_dynlib / size_default_dynlib_type; j++)
    {
        if (strcmp(symbol, default_dynlib_m[j].symbol) == 0)
        {
            val = default_dynlib_m[j].func;
            result = val;
            l_debug("find symbol \"%s\".  %p", symbol, result);
            break;
        }
    }
    if (!result)
        l_error("dlsym: Unknown symbol \"%s\".", symbol);
    return result;
}

void *dlopen_soloader(const char *file, int mode)
{
    l_debug("dlopen_soloader \"%s\".  mode:%p", file, mode);

    return default_dynlib_m;
}

int fprintf0(FILE *stream, const char *format, char *a1, int a3, char *a2)
{
    l_debug("fprintf");
    l_debug(format, a1, a3, a2);
    return 0;
}

int libandroidfw(void)
{
    l_debug("libandroidfw");
    return 0;
}

int libutils(void)
{
    l_debug("libutils");
    return 0;
}

int libmedia(void)
{
    l_debug("libmedia");
    return 0;
}

int setjmp0(jmp_buf v)
{
    l_debug("setjmp0");
    return setjmp(v);
}

int jniRegisterNativeMethods(int a1, int a2, int a3, int a4)
{
    l_debug("jniRegisterNativeMethods(%p,%s,%p,%d)", a1, a2, a3, a4);
    char **a = (char **)a3;
    l_debug("jniRegisterNativeMethods a3(%s,%s)", a[1], a[2]);

    return 0;
}

so_default_dynlib default_dynlib[] = {
    // MD5 Impl
    {"MD5_Init", (uintptr_t)&MD5_Init},
    {"MD5_Update", (uintptr_t)&MD5_Update},
    {"MD5_Final", (uintptr_t)&MD5_Final},

    // additional aeabi hook
    {"__aeabi_i2f", (uintptr_t)&__aeabi_i2f},
    {"__aeabi_fmul", (uintptr_t)&__aeabi_fmul},
    {"__aeabi_f2iz", (uintptr_t)&__aeabi_f2iz},

    // Android String8
    {"_ZN7android7String8C1Ev", (uintptr_t)&android_String8_init},
    {"_ZN7android7String8C1EPKc", (uintptr_t)&android_String8_initFromCstring},
    {"_ZN7android7String8C1ERKS0_", (uintptr_t)&android_String8_initFromString8},
    {"_ZN7android7String8D1Ev", (uintptr_t)&android_String8_term},
    {"_ZN7android7String85setToEPKc", (uintptr_t)&android_String8_setToCstring},
    {"_ZN7android7String86appendEPKc", (uintptr_t)&android_String8_appendCstring},
    {"_ZN7android7String86appendERKS0_", (uintptr_t)&android_String8_append},
    {"_ZN7android7String810appendPathEPKc", (uintptr_t)&android_String8_appendPathCstring},
    {"_ZNK7android7String810getPathDirEv", (uintptr_t)&android_String8_getPathDir},
    {"_ZNK7android7String88walkPathEPS0_", (uintptr_t)&android_String8_walkPath},

    // Android SharedBuffer
    {"_ZNK7android12SharedBuffer7acquireEv", (uintptr_t)&android_SharedBuffer_acquire},
    {"_ZN7android12SharedBuffer5allocEj", (uintptr_t)&android_SharedBuffer_alloc},
    {"_ZNK7android12SharedBuffer11attemptEditEv", (uintptr_t)&android_SharedBuffer_attemptEdit},
    {"_ZN7android12SharedBuffer7deallocEPKS0_", (uintptr_t)&android_SharedBuffer_dealloc},
    {"_ZNK7android12SharedBuffer10editResizeEj", (uintptr_t)&android_SharedBuffer_editResize},
    {"_ZNK7android12SharedBuffer7releaseEj", (uintptr_t)&android_SharedBuffer_release},

    // Android RefBase
    {"_ZN7android7RefBaseC2Ev", (uintptr_t)&_ZN7android7RefBaseC2Ev},
    {"_ZN7android7RefBaseD2Ev", (uintptr_t)&_ZN7android7RefBaseD2Ev},
    {"_ZN7android7RefBase10onFirstRefEv", (uintptr_t)&_ZN7android7RefBase10onFirstRefEv},
    {"_ZN7android7RefBase15onLastStrongRefEPKv", (uintptr_t)&_ZN7android7RefBase15onLastStrongRefEPKv},
    {"_ZN7android7RefBase13onLastWeakRefEPKv", (uintptr_t)&_ZN7android7RefBase13onLastWeakRefEPKv},
    {"_ZN7android7RefBase20onIncStrongAttemptedEjPKv", (uintptr_t)&_ZN7android7RefBase20onIncStrongAttemptedEjPKv},

    // Android Thread
    {"_ZN7android6ThreadC2Eb", (uintptr_t)&_ZN7android6ThreadC2Eb},
    {"_ZN7android6ThreadD0Ev", (uintptr_t)&_ZN7android6ThreadD0Ev},
    {"_ZN7android6ThreadD1Ev", (uintptr_t)&_ZN7android6ThreadD1Ev},
    {"_ZN7android6ThreadD2Ev", (uintptr_t)&_ZN7android6ThreadD2Ev},
    {"_ZN7android6Thread10readyToRunEv", (uintptr_t)&_ZN7android6Thread10readyToRunEv},
    {"_ZN7android6Thread11requestExitEv", (uintptr_t)&_ZN7android6Thread11requestExitEv},
    {"_ZN7android6Thread3runEPKcij", (uintptr_t)&_ZN7android6Thread3runEPKcij},

    // Android RefBase
    {"_ZN7android7RefBaseC2Ev", (uintptr_t)&ret0},
    {"_ZNK7android7RefBase9decStrongEPKv", (uintptr_t)&_ZNK7android7RefBase9incStrongEPKv},
    {"_ZNK7android7RefBase9incStrongEPKv", (uintptr_t)&_ZNK7android7RefBase9incStrongEPKv},
    {"_ZN7android7RefBase10onFirstRefEv", (uintptr_t)&ret0},
    {"_ZN7android7RefBase20onIncStrongAttemptedEjPKv", (uintptr_t)&ret0},
    {"_ZN7android7RefBase15onLastStrongRefEPKv", (uintptr_t)&ret0},
    {"_ZN7android7RefBase13onLastWeakRefEPKv", (uintptr_t)&ret0},
    {"_ZN7android7RefBaseD2Ev", (uintptr_t)&ret0},

    {"_ZNSt8bad_castD1Ev", (uintptr_t)&_ZNSt8bad_castD1Ev},
    {"_ZNSt9exceptionD2Ev", (uintptr_t)&_ZNSt9exceptionD2Ev},
    {"_ZSt17__throw_bad_allocv", (uintptr_t)&_ZSt17__throw_bad_allocv},
    {"_ZSt9terminatev", (uintptr_t)&_ZSt9terminatev},
    {"_ZTISt8bad_cast", (uintptr_t)&_ZTISt8bad_cast},
    {"_ZTISt9exception", (uintptr_t)&_ZTISt9exception},
    {"_ZTVN10__cxxabiv117__class_type_infoE", (uintptr_t)&_ZTVN10__cxxabiv117__class_type_infoE},
    {"_ZTVN10__cxxabiv120__si_class_type_infoE", (uintptr_t)&_ZTVN10__cxxabiv120__si_class_type_infoE},
    {"_ZTVN10__cxxabiv121__vmi_class_type_infoE", (uintptr_t)&_ZTVN10__cxxabiv121__vmi_class_type_infoE},
    {"_ZdaPv", (uintptr_t)&_ZdaPv},
    {"_ZdlPv", (uintptr_t)&_ZdlPv},
    {"_Znaj", (uintptr_t)&_Znaj},
    {"_Znwj", (uintptr_t)&_Znwj},
    {"__aeabi_atexit", (uintptr_t)&__aeabi_atexit},
    {"__aeabi_d2lz", (uintptr_t)&__aeabi_d2lz},
    {"__aeabi_d2ulz", (uintptr_t)&__aeabi_d2ulz},
    {"__aeabi_dadd", (uintptr_t)&__aeabi_dadd},
    {"__aeabi_dcmpgt", (uintptr_t)&__aeabi_dcmpgt},
    {"__aeabi_dcmplt", (uintptr_t)&__aeabi_dcmplt},
    {"__aeabi_ddiv", (uintptr_t)&__aeabi_ddiv},
    {"__aeabi_dmul", (uintptr_t)&__aeabi_dmul},
    {"__aeabi_f2lz", (uintptr_t)&__aeabi_f2lz},
    {"__aeabi_f2ulz", (uintptr_t)&__aeabi_f2ulz},
    {"__aeabi_i2d", (uintptr_t)&__aeabi_i2d},
    {"__aeabi_idiv", (uintptr_t)&__aeabi_idiv},
    {"__aeabi_idivmod", (uintptr_t)&__aeabi_idivmod},
    {"__aeabi_l2d", (uintptr_t)&__aeabi_l2d},
    {"__aeabi_l2f", (uintptr_t)&__aeabi_l2f},
    {"__aeabi_ldivmod", (uintptr_t)&__aeabi_ldivmod},
    {"__aeabi_llsl", (uintptr_t)&__aeabi_llsl},
    {"__aeabi_memclr", (uintptr_t)&__aeabi_memclr},
    {"__aeabi_memclr4", (uintptr_t)&__aeabi_memclr},
    {"__aeabi_memclr8", (uintptr_t)&__aeabi_memclr},
    {"__aeabi_memcpy", (uintptr_t)&sceClibMemcpy},
    {"__aeabi_memcpy4", (uintptr_t)&sceClibMemcpy},
    {"__aeabi_memcpy8", (uintptr_t)&sceClibMemcpy},
    {"__aeabi_memmove", (uintptr_t)&__aeabi_memmove},
    {"__aeabi_memmove4", (uintptr_t)&__aeabi_memmove},
    {"__aeabi_memmove8", (uintptr_t)&__aeabi_memmove},
    {"__aeabi_memset", (uintptr_t)&__aeabi_memset},
    {"__aeabi_memset4", (uintptr_t)&__aeabi_memset4},
    {"__aeabi_memset8", (uintptr_t)&__aeabi_memset8},
    {"__aeabi_ui2d", (uintptr_t)&__aeabi_ui2d},
    {"__aeabi_uidiv", (uintptr_t)&__aeabi_uidiv},
    {"__aeabi_uidivmod", (uintptr_t)&__aeabi_uidivmod},
    {"__aeabi_ul2d", (uintptr_t)&__aeabi_ul2d},
    {"__aeabi_ul2f", (uintptr_t)&__aeabi_ul2f},
    {"__aeabi_uldivmod", (uintptr_t)&__aeabi_uldivmod},
    {"__aeabi_unwind_cpp_pr0", (uintptr_t)&__aeabi_unwind_cpp_pr0},
    {"__aeabi_unwind_cpp_pr1", (uintptr_t)&__aeabi_unwind_cpp_pr1},
    {"__atomic_cmpxchg", (uintptr_t)&__atomic_cmpxchg},
    {"__atomic_dec", (uintptr_t)&__atomic_dec},
    {"__atomic_inc", (uintptr_t)&__atomic_inc},
    {"__atomic_swap", (uintptr_t)&__atomic_swap},
    {"__cxa_allocate_exception", (uintptr_t)&__cxa_allocate_exception},
    {"__cxa_atexit", (uintptr_t)&__cxa_atexit},
    {"__cxa_begin_catch", (uintptr_t)&__cxa_begin_catch},
    {"__cxa_begin_cleanup", (uintptr_t)&ret0},
    {"__cxa_call_unexpected", (uintptr_t)&__cxa_call_unexpected},
    {"__cxa_end_catch", (uintptr_t)&__cxa_end_catch},
    {"__cxa_finalize", (uintptr_t)&__cxa_finalize},
    {"__cxa_free_exception", (uintptr_t)&__cxa_free_exception},
    {"__cxa_guard_acquire", (uintptr_t)&__cxa_guard_acquire},
    {"__cxa_guard_release", (uintptr_t)&__cxa_guard_release},
    {"__cxa_pure_virtual", (uintptr_t)&__cxa_pure_virtual},
    {"__cxa_rethrow", (uintptr_t)&__cxa_rethrow},
    {"__cxa_throw", (uintptr_t)&__cxa_throw},
    {"__cxa_type_match", (uintptr_t)&ret0},
    {"__gnu_Unwind_Find_exidx", (uintptr_t)&ret0},
    {"__gnu_ldivmod_helper", (uintptr_t)&__gnu_ldivmod_helper},
    {"__gnu_unwind_frame", (uintptr_t)&__gnu_unwind_frame},
    {"__google_potentially_blocking_region_begin", (uintptr_t)&ret0},
    {"__google_potentially_blocking_region_end", (uintptr_t)&ret0},
    {"__gxx_personality_v0", (uintptr_t)&__gxx_personality_v0},
    {"__isinf", (uintptr_t)&ret0},
    {"__page_size", (uintptr_t)&__page_size},
    {"__sF", (uintptr_t)&__sF_fake},
    {"__srget", (uintptr_t)&__srget},
    {"__stack_chk_fail", (uintptr_t)&__stack_chk_fail_soloader},
    {"__stack_chk_guard", (uintptr_t)&__stack_chk_guard},
    {"__swbuf", (uintptr_t)&__swbuf},
    {"__system_property_get", (uintptr_t)&__system_property_get_soloader},

    // ctype
    {"_ctype_", (uintptr_t)&BIONIC_ctype_},
    {"_tolower_tab_", (uintptr_t)&BIONIC_tolower_tab_},
    {"_toupper_tab_", (uintptr_t)&BIONIC_toupper_tab_},
    {"isalnum", (uintptr_t)&isalnum},
    {"isalpha", (uintptr_t)&isalpha},
    {"isblank", (uintptr_t)&isblank},
    {"iscntrl", (uintptr_t)&iscntrl},
    {"isgraph", (uintptr_t)&isgraph},
    {"islower", (uintptr_t)&islower},
    {"isprint", (uintptr_t)&isprint},
    {"ispunct", (uintptr_t)&ispunct},
    {"isspace", (uintptr_t)&isspace},
    {"isupper", (uintptr_t)&isupper},
    {"isxdigit", (uintptr_t)&isxdigit},
    {"tolower", (uintptr_t)&tolower},
    {"toupper", (uintptr_t)&toupper},

    // Android SDK standard logging
    {"__android_log_assert", (uintptr_t)&__android_log_assert},
    {"__android_log_print", (uintptr_t)&__android_log_print},
    {"__android_log_vprint", (uintptr_t)&__android_log_vprint},
    {"__android_log_write", (uintptr_t)&__android_log_write},

    // AAssetManager
    {"AAsset_close", (uintptr_t)&AAsset_close},
    {"AAsset_getLength", (uintptr_t)&AAsset_getLength},
    {"AAsset_getRemainingLength", (uintptr_t)&AAsset_getRemainingLength},
    {"AAsset_read", (uintptr_t)&AAsset_read},
    {"AAsset_seek", (uintptr_t)&AAsset_seek},
    {"AAssetDir_close", (uintptr_t)&AAssetDir_close},
    {"AAssetManager_fromJava", (uintptr_t)&ret1},
    {"AAssetManager_open", (uintptr_t)&AAssetManager_open},
    {"AAssetManager_openDir", (uintptr_t)&AAssetManager_openDir},

    // Math
    {"acos", (uintptr_t)&acos},
    {"acosf", (uintptr_t)&acosf},
    {"asin", (uintptr_t)&asin},
    {"asinf", (uintptr_t)&asinf},
    {"atan", (uintptr_t)&atan},
    {"atan2", (uintptr_t)&atan2},
    {"atan2f", (uintptr_t)&atan2f},
    {"atanf", (uintptr_t)&atanf},
    {"ceil", (uintptr_t)&ceil},
    {"ceilf", (uintptr_t)&ceilf},
    {"cos", (uintptr_t)&cos},
    {"cosf", (uintptr_t)&cosf},
    {"exp", (uintptr_t)&exp},
    {"exp2", (uintptr_t)&exp2},
    {"exp2f", (uintptr_t)&exp2f},
    {"expf", (uintptr_t)&expf},
    {"floor", (uintptr_t)&floor},
    {"floorf", (uintptr_t)&floorf},
    {"fmod", (uintptr_t)&fmod},
    {"fmodf", (uintptr_t)&fmodf},
    {"frexp", (uintptr_t)&frexp},
    {"ldexp", (uintptr_t)&ldexp},
    {"ldexpf", (uintptr_t)&ldexpf},
    {"log", (uintptr_t)&log},
    {"log10", (uintptr_t)&log10},
    {"log10f", (uintptr_t)&log10f},
    {"logf", (uintptr_t)&logf},
    {"lrint", (uintptr_t)&lrint},
    {"lrintf", (uintptr_t)&lrintf},
    {"lround", (uintptr_t)&lround},
    {"lroundf", (uintptr_t)&lroundf},
    {"modf", (uintptr_t)&modf},
    {"pow", (uintptr_t)&pow},
    {"powf", (uintptr_t)&powf},
    {"rint", (uintptr_t)&rint},
    {"rintf", (uintptr_t)&rintf},
    {"round", (uintptr_t)&round},
    {"roundf", (uintptr_t)&roundf},
    {"scalbn", (uintptr_t)&scalbn},
    {"scalbnf", (uintptr_t)&scalbnf},
    {"sin", (uintptr_t)&sin},
    {"sincos", (uintptr_t)&sincos},
    {"sincosf", (uintptr_t)&sincosf},
    {"sinf", (uintptr_t)&sinf},
    {"sinh", (uintptr_t)&sinh},
    {"sinhf", (uintptr_t)&sinhf},
    {"sqrt", (uintptr_t)&sqrt},
    {"sqrtf", (uintptr_t)&sqrtf},
    {"tan", (uintptr_t)&tan},
    {"tanf", (uintptr_t)&tanf},
    {"tanh", (uintptr_t)&tanh},
    {"trunc", (uintptr_t)&trunc},
    {"truncf", (uintptr_t)&truncf},

    // Sockets
    {"accept", (uintptr_t)&accept},
    {"bind", (uintptr_t)&bind},
    {"connect", (uintptr_t)&connect},
    {"freeaddrinfo", (uintptr_t)&freeaddrinfo},
    {"getaddrinfo", (uintptr_t)&getaddrinfo},
    {"gethostbyaddr", (uintptr_t)&gethostbyaddr},
    {"gethostbyname", (uintptr_t)&gethostbyname},
    {"gethostname", (uintptr_t)&gethostname},
    {"getpeername", (uintptr_t)&getpeername},
    {"getservbyname", (uintptr_t)&getservbyname},
    {"getsockname", (uintptr_t)&getsockname},
    {"getsockopt", (uintptr_t)&getsockopt},
    {"inet_aton", (uintptr_t)&inet_aton},
    {"inet_ntoa", (uintptr_t)&inet_ntoa},
    {"inet_ntop", (uintptr_t)&inet_ntop},
    {"inet_addr", (uintptr_t)&inet_addr},
    {"listen", (uintptr_t)&listen},
    {"poll", (uintptr_t)&poll},
    {"recv", (uintptr_t)&recv},
    {"recvfrom", (uintptr_t)&recvfrom},
    {"recvmsg", (uintptr_t)&recvmsg},
    {"select", (uintptr_t)&select},
    {"send", (uintptr_t)&send},
    {"sendmsg", (uintptr_t)&sendmsg},
    {"sendto", (uintptr_t)&sendto},
    {"setsockopt", (uintptr_t)&setsockopt},
    {"shutdown", (uintptr_t)&shutdown},
    {"socket", (uintptr_t)&socket},

    // Memory
    {"calloc", (uintptr_t)&calloc},
    {"free", (uintptr_t)&free},
    {"malloc", (uintptr_t)&malloc},
    {"memalign", (uintptr_t)&memalign},
    {"memcmp", (uintptr_t)&memcmp},
    {"memcpy", (uintptr_t)&sceClibMemcpy},
    {"memmem", (uintptr_t)&memmem},
    {"memmove", (uintptr_t)&memmove},
    {"memset", (uintptr_t)&memset},
    {"mmap", (uintptr_t)&mmap},
    {"munmap", (uintptr_t)&munmap},
    {"realloc", (uintptr_t)&realloc},
    {"valloc", (uintptr_t)&valloc},

    // IO
    {"close", (uintptr_t)&close_soloader},
    {"closedir", (uintptr_t)&closedir_soloader},
    {"execv", (uintptr_t)&ret0},
    {"fclose", (uintptr_t)&fclose_soloader},
    {"fcntl", (uintptr_t)&fcntl_soloader},
    {"fopen", (uintptr_t)&fopen_soloader},
    {"fstat", (uintptr_t)&fstat_soloader},
    {"fsync", (uintptr_t)&fsync_soloader},
    {"ioctl", (uintptr_t)&ioctl_soloader},
    {"open", (uintptr_t)&open_soloader},
    {"opendir", (uintptr_t)&opendir_soloader},
    {"readdir", (uintptr_t)&readdir_soloader},
    {"readdir_r", (uintptr_t)&readdir_r_soloader},
    {"stat", (uintptr_t)&stat_soloader},
    {"utime", (uintptr_t)&utime},
    {"ftime", (uintptr_t)&ftime},

#ifdef USE_SCELIBC_IO
    {"fdopen", (uintptr_t)&fdopen_soloader},
    {"feof", (uintptr_t)&sceLibcBridge_feof},
    {"ferror", (uintptr_t)&sceLibcBridge_ferror},
    {"fflush", (uintptr_t)&sceLibcBridge_fflush},
    {"fgetc", (uintptr_t)&sceLibcBridge_fgetc},
    {"fgetpos", (uintptr_t)&sceLibcBridge_fgetpos},
    {"fgets", (uintptr_t)&sceLibcBridge_fgets},
    {"fileno", (uintptr_t)&sceLibcBridge_fileno},
    {"fputc", (uintptr_t)&sceLibcBridge_fputc},
    {"fputs", (uintptr_t)&sceLibcBridge_fputs},
    {"fread", (uintptr_t)&sceLibcBridge_fread},
    {"freopen", (uintptr_t)&sceLibcBridge_freopen},
    {"fseek", (uintptr_t)&sceLibcBridge_fseek},
    {"fsetpos", (uintptr_t)&sceLibcBridge_fsetpos},
    {"ftell", (uintptr_t)&sceLibcBridge_ftell},
    {"fwide", (uintptr_t)&sceLibcBridge_fwide},
    {"fwrite", (uintptr_t)&sceLibcBridge_fwrite},
    {"getc", (uintptr_t)&sceLibcBridge_getc},
    {"getwc", (uintptr_t)&sceLibcBridge_getwc},
    {"putc", (uintptr_t)&sceLibcBridge_putc},
    {"putchar", (uintptr_t)&sceLibcBridge_putchar},
    {"puts", (uintptr_t)&sceLibcBridge_puts},
    {"putwc", (uintptr_t)&sceLibcBridge_putwc},
    {"setvbuf", (uintptr_t)&sceLibcBridge_setvbuf},
    {"ungetc", (uintptr_t)&sceLibcBridge_ungetc},
    {"ungetwc", (uintptr_t)&sceLibcBridge_ungetwc},
#else
    {"fdopen", (uintptr_t)&fdopen_soloader},
    {"feof", (uintptr_t)&feof},
    {"ferror", (uintptr_t)&ferror},
    {"fflush", (uintptr_t)&fflush},
    {"fgetc", (uintptr_t)&fgetc},
    {"fgetpos", (uintptr_t)&fgetpos},
    {"fgets", (uintptr_t)&fgets},
    {"fileno", (uintptr_t)&fileno},
    {"fputc", (uintptr_t)&fputc},
    {"fputs", (uintptr_t)&fputs},
    {"fread", (uintptr_t)&fread},
    {"freopen", (uintptr_t)&freopen},
    {"fseek", (uintptr_t)&fseek},
    {"fsetpos", (uintptr_t)&fsetpos},
    {"ftell", (uintptr_t)&ftell},
    {"fwide", (uintptr_t)&fwide},
    {"fwrite", (uintptr_t)&fwrite},
    {"getc", (uintptr_t)&getc},
    {"getwc", (uintptr_t)&getwc},
    {"putc", (uintptr_t)&putc},
    {"putchar", (uintptr_t)&putchar},
    {"puts", (uintptr_t)&puts},
    {"putwc", (uintptr_t)&putwc},
    {"setvbuf", (uintptr_t)&setvbuf},
    {"ungetc", (uintptr_t)&ungetc},
    {"ungetwc", (uintptr_t)&ungetwc},
#endif

    {"access", (uintptr_t)&access},
    {"basename", (uintptr_t)&basename},
    {"chdir", (uintptr_t)&chdir_wrap},
    // { "chdir", (uintptr_t)&chdir },
    {"chmod", (uintptr_t)&chmod},
    {"dup", (uintptr_t)&dup_soloader},
    {"fseeko", (uintptr_t)&fseeko}, // TODO: wrap normal fseek for SceLibc version?
    {"ftello", (uintptr_t)&ftello},
    {"ftruncate", (uintptr_t)&ftruncate},
    {"getcwd", (uintptr_t)&getcwd},
    {"lseek", (uintptr_t)&lseek},
    {"lstat", (uintptr_t)&lstat},
    {"mkdir", (uintptr_t)&mkdir},
    {"pipe", (uintptr_t)&pipe},
    {"read", (uintptr_t)&read},
    {"realpath", (uintptr_t)&realpath},
    {"remove", (uintptr_t)&remove},
    {"rename", (uintptr_t)&rename},
    {"rewind", (uintptr_t)&rewind},
    {"rmdir", (uintptr_t)&rmdir},
    {"truncate", (uintptr_t)&truncate},
    {"unlink", (uintptr_t)&unlink},
    {"write", (uintptr_t)&write},

    // *printf, *scanf
    {"snprintf", (uintptr_t)&snprintf},
    {"sprintf", (uintptr_t)&sprintf},
    {"vasprintf", (uintptr_t)&vasprintf},
    {"vprintf", (uintptr_t)&vprintf},
    {"vsnprintf", (uintptr_t)&vsnprintf},
    {"vsprintf", (uintptr_t)&vsprintf},
    {"vsscanf", (uintptr_t)&vsscanf},
    {"vswprintf", (uintptr_t)&vswprintf},
    {"printf", (uintptr_t)&sceClibPrintf},
    {"swprintf", (uintptr_t)&swprintf},

#ifdef USE_SCELIBC_IO
    {"fprintf", (uintptr_t)&sceLibcBridge_fprintf},
    {"fscanf", (uintptr_t)&sceLibcBridge_fscanf},
    {"sscanf", (uintptr_t)&sceLibcBridge_sscanf},
    {"vfprintf", (uintptr_t)&sceLibcBridge_vfprintf},
#else
    {"fprintf", (uintptr_t)&fprintf0},
    {"fscanf", (uintptr_t)&fscanf},
    {"sscanf", (uintptr_t)&sscanf},
    {"vfprintf", (uintptr_t)&vfprintf},
#endif

    // EGL
    {"eglBindAPI", (uintptr_t)&eglBindAPI},
    {"eglChooseConfig", (uintptr_t)&eglChooseConfig},
    {"eglCreateContext", (uintptr_t)&eglCreateContext},
    {"eglCreateWindowSurface", (uintptr_t)&eglCreateWindowSurface},
    {"eglDestroyContext", (uintptr_t)&eglDestroyContext},
    {"eglDestroySurface", (uintptr_t)&eglDestroySurface},
    {"eglGetConfigAttrib", (uintptr_t)&eglGetConfigAttrib},
    {"eglGetConfigs", (uintptr_t)&eglGetConfigs},
    {"eglGetCurrentContext", (uintptr_t)&eglGetCurrentContext},
    {"eglGetDisplay", (uintptr_t)&eglGetDisplay},
    {"eglGetError", (uintptr_t)&eglGetError},
    {"eglGetProcAddress", (uintptr_t)&eglGetProcAddress},
    {"eglInitialize", (uintptr_t)&eglInitialize},
    {"eglMakeCurrent", (uintptr_t)&eglMakeCurrent},
    {"eglQueryContext", (uintptr_t)&eglQueryContext},
    {"eglQueryString", (uintptr_t)&eglQueryString},
    {"eglQuerySurface", (uintptr_t)&eglQuerySurface},
    {"eglSwapBuffers", (uintptr_t)&eglSwapBuffers},
    {"eglTerminate", (uintptr_t)&eglTerminate},

    // additional EGL Hook
    {"eglGetCurrentDisplay", (uintptr_t)&ret0},
    {"eglSwapInterval", (uintptr_t)&ret0},
    {"eglCreatePbufferSurface", (uintptr_t)&ret0},
    {"eglCreatePixmapSurface", (uintptr_t)&ret0},
    {"eglQueryAPI", (uintptr_t)&ret0},
    {"eglWaitClient", (uintptr_t)&ret0},
    {"eglCreatePbufferFromClientBuffer", (uintptr_t)&ret0},
    {"eglSurfaceAttrib", (uintptr_t)&ret0},
    {"eglBindTexImage", (uintptr_t)&ret0},
    {"eglReleaseTexImage", (uintptr_t)&ret0},
    {"eglGetCurrentSurface", (uintptr_t)&ret0},
    {"eglWaitGL", (uintptr_t)&ret0},
    {"eglWaitNative", (uintptr_t)&ret0},
    {"eglCopyBuffers", (uintptr_t)&ret0},
    {"eglLockSurfaceKHR", (uintptr_t)&ret0},
    {"eglUnlockSurfaceKHR", (uintptr_t)&ret0},

    // OpenGL
    {"glActiveTexture", (uintptr_t)&glActiveTexture},
    {"glAlphaFunc", (uintptr_t)&glAlphaFunc},
    {"glAlphaFuncx", (uintptr_t)&glAlphaFuncx},
    {"glAttachShader", (uintptr_t)&glAttachShader},
    {"glBindAttribLocation", (uintptr_t)&glBindAttribLocation},
    {"glBindBuffer", (uintptr_t)&glBindBuffer},
    {"glBindFramebuffer", (uintptr_t)&glBindFramebuffer},
    {"glBindFramebufferOES", (uintptr_t)&glBindFramebuffer},
    {"glBindRenderbuffer", (uintptr_t)&glBindRenderbuffer},
    {"glBindRenderbufferOES", (uintptr_t)&glBindRenderbuffer},
    {"glBindTexture", (uintptr_t)&glBindTexture},
    {"glBlendColor", (uintptr_t)&ret0},
    {"glBlendEquation", (uintptr_t)&glBlendEquation},
    {"glBlendEquationOES", (uintptr_t)&glBlendEquation},
    {"glBlendEquationSeparate", (uintptr_t)&glBlendEquationSeparate},
    {"glBlendEquationSeparateOES", (uintptr_t)&glBlendEquationSeparate},
    {"glBlendFunc", (uintptr_t)&glBlendFunc},
    {"glBlendFuncSeparate", (uintptr_t)&glBlendFuncSeparate},
    {"glBlendFuncSeparateOES", (uintptr_t)&glBlendFuncSeparate},
    {"glBufferData", (uintptr_t)&glBufferData},
    {"glBufferSubData", (uintptr_t)&glBufferSubData},
    {"glCheckFramebufferStatus", (uintptr_t)&glCheckFramebufferStatus},
    {"glCheckFramebufferStatusOES", (uintptr_t)&glCheckFramebufferStatus},
    {"glClear", (uintptr_t)&glClear},
    {"glClearColor", (uintptr_t)&glClearColor},
    {"glClearColorx", (uintptr_t)&glClearColorx},
    {"glClearDepthf", (uintptr_t)&glClearDepthf},
    {"glClearDepthx", (uintptr_t)&glClearDepthx},
    {"glClearStencil", (uintptr_t)&glClearStencil},
    {"glClientActiveTexture", (uintptr_t)&glClientActiveTexture},
    {"glClipPlanef", (uintptr_t)&glClipPlanef},
    {"glClipPlanex", (uintptr_t)&glClipPlanex},
    {"glColor4f", (uintptr_t)&glColor4f},
    {"glColor4ub", (uintptr_t)&glColor4ub},
    {"glColor4x", (uintptr_t)&glColor4x},
    {"glColorMask", (uintptr_t)&glColorMask},
    {"glColorPointer", (uintptr_t)&glColorPointer},
    {"glCompileShader", (uintptr_t)&glCompileShader_soloader},
    {"glCompressedTexImage2D", (uintptr_t)&glCompressedTexImage2D},
    {"glCompressedTexSubImage2D", (uintptr_t)&ret0},
    {"glCopyTexImage2D", (uintptr_t)&glCopyTexImage2D},
    {"glCopyTexSubImage2D", (uintptr_t)&glCopyTexSubImage2D},
    {"glCreateProgram", (uintptr_t)&glCreateProgram},
    {"glCreateShader", (uintptr_t)&glCreateShader},
    {"glCullFace", (uintptr_t)&glCullFace},
    {"glCurrentPaletteMatrixOES", (uintptr_t)&ret0},
    {"glDeleteBuffers", (uintptr_t)&glDeleteBuffers},
    {"glDeleteFramebuffers", (uintptr_t)&glDeleteFramebuffers},
    {"glDeleteFramebuffersOES", (uintptr_t)&glDeleteFramebuffers},
    {"glDeleteProgram", (uintptr_t)&glDeleteProgram},
    {"glDeleteRenderbuffers", (uintptr_t)&glDeleteRenderbuffers},
    {"glDeleteRenderbuffersOES", (uintptr_t)&glDeleteRenderbuffers},
    {"glDeleteShader", (uintptr_t)&glDeleteShader},
    {"glDeleteTextures", (uintptr_t)&glDeleteTextures},
    {"glDepthFunc", (uintptr_t)&glDepthFunc},
    {"glDepthMask", (uintptr_t)&glDepthMask},
    {"glDepthRangef", (uintptr_t)&glDepthRangef},
    {"glDepthRangex", (uintptr_t)&glDepthRangex},
    {"glDetachShader", (uintptr_t)&ret0},
    {"glDisable", (uintptr_t)&glDisable},
    {"glDisableClientState", (uintptr_t)&glDisableClientState},
    {"glDisableVertexAttribArray", (uintptr_t)&glDisableVertexAttribArray},
    {"glDrawArrays", (uintptr_t)&glDrawArrays},
    {"glDrawElements", (uintptr_t)&glDrawElements},
    {"glDrawTexfOES", (uintptr_t)&ret0},
    {"glDrawTexfvOES", (uintptr_t)&ret0},
    {"glDrawTexiOES", (uintptr_t)&ret0},
    {"glDrawTexivOES", (uintptr_t)&ret0},
    {"glDrawTexsOES", (uintptr_t)&ret0},
    {"glDrawTexsvOES", (uintptr_t)&ret0},
    {"glDrawTexxOES", (uintptr_t)&ret0},
    {"glDrawTexxvOES", (uintptr_t)&ret0},
    {"glEGLImageTargetRenderbufferStorageOES", (uintptr_t)&ret0},
    {"glEGLImageTargetTexture2DOES", (uintptr_t)&ret0},
    {"glEnable", (uintptr_t)&glEnable},
    {"glEnableClientState", (uintptr_t)&glEnableClientState},
    {"glEnableVertexAttribArray", (uintptr_t)&glEnableVertexAttribArray},
    {"glFinish", (uintptr_t)&glFinish},
    {"glFlush", (uintptr_t)&glFlush},
    {"glFogf", (uintptr_t)&glFogf},
    {"glFogfv", (uintptr_t)&glFogfv},
    {"glFogx", (uintptr_t)&glFogx},
    {"glFogxv", (uintptr_t)&glFogxv},
    {"glFramebufferRenderbuffer", (uintptr_t)&glFramebufferRenderbuffer},
    {"glFramebufferRenderbufferOES", (uintptr_t)&glFramebufferRenderbuffer},
    {"glFramebufferTexture2D", (uintptr_t)&glFramebufferTexture2D},
    {"glFramebufferTexture2DOES", (uintptr_t)&glFramebufferTexture2D},
    {"glFrontFace", (uintptr_t)&glFrontFace},
    {"glFrustumf", (uintptr_t)&glFrustumf},
    {"glFrustumx", (uintptr_t)&glFrustumx},
    {"glGenBuffers", (uintptr_t)&glGenBuffers},
    {"glGenerateMipmap", (uintptr_t)&glGenerateMipmap},
    {"glGenerateMipmapOES", (uintptr_t)&glGenerateMipmap},
    {"glGenFramebuffers", (uintptr_t)&glGenFramebuffers},
    {"glGenFramebuffersOES", (uintptr_t)&glGenFramebuffers},
    {"glGenRenderbuffers", (uintptr_t)&glGenRenderbuffers},
    {"glGenRenderbuffersOES", (uintptr_t)&glGenRenderbuffers},
    {"glGenTextures", (uintptr_t)&glGenTextures},
    {"glGetActiveAttrib", (uintptr_t)&glGetActiveAttrib},
    {"glGetActiveUniform", (uintptr_t)&glGetActiveUniform},
    {"glGetAttribLocation", (uintptr_t)&glGetAttribLocation},
    {"glGetBooleanv", (uintptr_t)&glGetBooleanv},
    {"glGetBufferParameteriv", (uintptr_t)&glGetBufferParameteriv},
    {"glGetBufferPointervOES", (uintptr_t)&ret0},
    {"glGetClipPlanef", (uintptr_t)&ret0},
    {"glGetClipPlanex", (uintptr_t)&ret0},
    {"glGetError", (uintptr_t)&glGetError},
    {"glGetFixedv", (uintptr_t)&ret0},
    {"glGetFloatv", (uintptr_t)&glGetFloatv},
    {"glGetFramebufferAttachmentParameterivOES", (uintptr_t)&glGetFramebufferAttachmentParameteriv},
    {"glGetIntegerv", (uintptr_t)&glGetIntegerv},
    {"glGetLightfv", (uintptr_t)&ret0},
    {"glGetLightxv", (uintptr_t)&ret0},
    {"glGetMaterialfv", (uintptr_t)&ret0},
    {"glGetMaterialxv", (uintptr_t)&ret0},
    {"glGetPointerv", (uintptr_t)&ret0},
    {"glGetRenderbufferParameterivOES", (uintptr_t)&ret0},
    {"glGetProgramInfoLog", (uintptr_t)&glGetProgramInfoLog},
    {"glGetProgramiv", (uintptr_t)&glGetProgramiv},
    {"glGetShaderInfoLog", (uintptr_t)&glGetShaderInfoLog},
    {"glGetShaderSource", (uintptr_t)&glGetShaderSource},
    {"glGetShaderiv", (uintptr_t)&glGetShaderiv},
    {"glGetString", (uintptr_t)&glGetString},
    {"glGetTexEnvfv", (uintptr_t)&ret0},
    {"glGetTexEnviv", (uintptr_t)&glGetTexEnviv},
    {"glGetTexEnvxv", (uintptr_t)&ret0},
    {"glGetTexGenfvOES", (uintptr_t)&ret0},
    {"glGetTexGenivOES", (uintptr_t)&ret0},
    {"glGetTexGenxvOES", (uintptr_t)&ret0},
    {"glGetTexParameterfv", (uintptr_t)&ret0},
    {"glGetTexParameteriv", (uintptr_t)&ret0},
    {"glGetTexParameterxv", (uintptr_t)&ret0},
    {"glGetUniformLocation", (uintptr_t)&glGetUniformLocation},
    {"glHint", (uintptr_t)&glHint},
    {"glIsBuffer", (uintptr_t)&ret0},
    {"glIsEnabled", (uintptr_t)&glIsEnabled},
    {"glIsFramebufferOES", (uintptr_t)&glIsFramebuffer},
    {"glIsRenderbufferOES", (uintptr_t)&glIsRenderbuffer},
    {"glIsTexture", (uintptr_t)&glIsTexture},
    {"glLightf", (uintptr_t)&ret0},
    {"glLightfv", (uintptr_t)&glLightfv},
    {"glLightModelf", (uintptr_t)&ret0},
    {"glLightModelfv", (uintptr_t)&glLightModelfv},
    {"glLightModelx", (uintptr_t)&ret0},
    {"glLightModelxv", (uintptr_t)&glLightModelxv},
    {"glLightx", (uintptr_t)&ret0},
    {"glLightxv", (uintptr_t)&glLightxv},
    {"glLineWidth", (uintptr_t)&glLineWidth},
    {"glLineWidthx", (uintptr_t)&glLineWidthx},
    {"glLinkProgram", (uintptr_t)&glLinkProgram},
    {"glLoadIdentity", (uintptr_t)&glLoadIdentity},
    {"glLoadMatrixf", (uintptr_t)&glLoadMatrixf},
    {"glLoadMatrixx", (uintptr_t)&glLoadMatrixx},
    {"glLoadPaletteFromModelViewMatrixOES", (uintptr_t)&ret0},
    {"glLogicOp", (uintptr_t)&ret0},
    {"glMapBuffer", (uintptr_t)&glMapBuffer},
    {"glMapBufferOES", (uintptr_t)&glMapBuffer},
    {"glMaterialf", (uintptr_t)&glMaterialf},
    {"glMaterialfv", (uintptr_t)&glMaterialfv},
    {"glMaterialx", (uintptr_t)&glMaterialx},
    {"glMaterialxv", (uintptr_t)&glMaterialxv},
    {"glMatrixIndexPointerOES", (uintptr_t)&ret0},
    {"glMatrixMode", (uintptr_t)&glMatrixMode},
    {"glMultiTexCoord4f", (uintptr_t)&ret0},
    {"glMultiTexCoord4x", (uintptr_t)&ret0},
    {"glMultMatrixf", (uintptr_t)&glMultMatrixf},
    {"glMultMatrixx", (uintptr_t)&glMultMatrixx},
    {"glNormal3f", (uintptr_t)&glNormal3f},
    {"glNormal3x", (uintptr_t)&glNormal3x},
    {"glNormalPointer", (uintptr_t)&glNormalPointer},
    {"glOrthof", (uintptr_t)&glOrthof},
    {"glOrthox", (uintptr_t)&glOrthox},
    {"glPixelStorei", (uintptr_t)&glPixelStorei},
    {"glPointParameterf", (uintptr_t)&ret0},
    {"glPointParameterfv", (uintptr_t)&ret0},
    {"glPointParameterx", (uintptr_t)&ret0},
    {"glPointParameterxv", (uintptr_t)&ret0},
    {"glPointSize", (uintptr_t)&glPointSize},
    {"glPointSizePointerOES", (uintptr_t)&ret0},
    {"glPointSizex", (uintptr_t)&glPointSizex},
    {"glPolygonOffset", (uintptr_t)&glPolygonOffset},
    {"glPolygonOffsetx", (uintptr_t)&glPolygonOffsetx},
    {"glPopMatrix", (uintptr_t)&glPopMatrix},
    {"glPushMatrix", (uintptr_t)&glPushMatrix},
    {"glQueryMatrixxOES", (uintptr_t)&ret0},
    {"glReadPixels", (uintptr_t)&glReadPixels},
    {"glRenderbufferStorage", (uintptr_t)&glRenderbufferStorage},
    {"glRenderbufferStorageOES", (uintptr_t)&glRenderbufferStorage},
    {"glRotatef", (uintptr_t)&glRotatef},
    {"glRotatex", (uintptr_t)&glRotatex},
    {"glSampleCoverage", (uintptr_t)&ret0},
    {"glSampleCoveragex", (uintptr_t)&ret0},
    {"glScalef", (uintptr_t)&glScalef},
    {"glScalex", (uintptr_t)&glScalex},
    {"glScissor", (uintptr_t)&glScissor},
    {"glShadeModel", (uintptr_t)&glShadeModel},
    {"glShaderSource", (uintptr_t)&glShaderSource_soloader},
    {"glStencilFunc", (uintptr_t)&glStencilFunc},
    {"glStencilFuncSeparate", (uintptr_t)&glStencilFuncSeparate},
    {"glStencilMask", (uintptr_t)&glStencilMask},
    {"glStencilOp", (uintptr_t)&glStencilOp},
    {"glStencilOpSeparate", (uintptr_t)&glStencilOpSeparate},
    {"glTexCoordPointer", (uintptr_t)&glTexCoordPointer},
    {"glTexEnvf", (uintptr_t)&glTexEnvf},
    {"glTexEnvfv", (uintptr_t)&glTexEnvfv},
    {"glTexEnvi", (uintptr_t)&glTexEnvi},
    {"glTexEnviv", (uintptr_t)&ret0},
    {"glTexEnvx", (uintptr_t)&glTexEnvx},
    {"glTexEnvxv", (uintptr_t)&glTexEnvxv},
    {"glTexGenfOES", (uintptr_t)&ret0},
    {"glTexGenfvOES", (uintptr_t)&ret0},
    {"glTexGeniOES", (uintptr_t)&ret0},
    {"glTexGenivOES", (uintptr_t)&ret0},
    {"glTexGenxOES", (uintptr_t)&ret0},
    {"glTexGenxvOES", (uintptr_t)&ret0},
    {"glTexImage2D", (uintptr_t)&glTexImage2D},
    {"glTexParameterf", (uintptr_t)&glTexParameterf},
    {"glTexParameterfv", (uintptr_t)&ret0},
    {"glTexParameteri", (uintptr_t)&glTexParameteri},
    {"glTexParameteriv", (uintptr_t)&glTexParameteriv},
    {"glTexParameterx", (uintptr_t)&glTexParameterx},
    {"glTexParameterxv", (uintptr_t)&ret0},
    {"glTexSubImage2D", (uintptr_t)&glTexSubImage2D},
    {"glTranslatef", (uintptr_t)&glTranslatef},
    {"glTranslatex", (uintptr_t)&glTranslatex},
    {"glUniform1f", (uintptr_t)&glUniform1f},
    {"glUniform1fv", (uintptr_t)&glUniform1fv},
    {"glUniform1i", (uintptr_t)&glUniform1i},
    {"glUniform1iv", (uintptr_t)&glUniform1iv},
    {"glUniform2f", (uintptr_t)&glUniform2f},
    {"glUniform2fv", (uintptr_t)&glUniform2fv},
    {"glUniform2iv", (uintptr_t)&glUniform2iv},
    {"glUniform3f", (uintptr_t)&glUniform3f},
    {"glUniform3fv", (uintptr_t)&glUniform3fv},
    {"glUniform3iv", (uintptr_t)&glUniform3iv},
    {"glUniform4f", (uintptr_t)&glUniform4f},
    {"glUniform4fv", (uintptr_t)&glUniform4fv},
    {"glUniform4iv", (uintptr_t)&glUniform4iv},
    {"glUniformMatrix2fv", (uintptr_t)&glUniformMatrix2fv},
    {"glUniformMatrix3fv", (uintptr_t)&glUniformMatrix3fv},
    {"glUniformMatrix4fv", (uintptr_t)&glUniformMatrix4fv},
    {"glUnmapBuffer", (uintptr_t)&glUnmapBuffer},
    {"glUnmapBufferOES", (uintptr_t)&glUnmapBuffer},
    {"glUseProgram", (uintptr_t)&glUseProgram},
    {"glValidateProgram", (uintptr_t)&ret0},
    {"glVertexAttrib4f", (uintptr_t)&glVertexAttrib4f},
    {"glVertexAttrib4fv", (uintptr_t)&glVertexAttrib4fv},
    {"glVertexAttribPointer", (uintptr_t)&glVertexAttribPointer},
    {"glVertexPointer", (uintptr_t)&glVertexPointer},
    {"glViewport", (uintptr_t)&glViewport},
    {"glWeightPointerOES", (uintptr_t)&ret0},

    // add gl
    {"glGetRenderbufferParameteriv", (uintptr_t)&ret0},
    {"glStencilMaskSeparate", (uintptr_t)&glStencilMaskSeparate},
    {"glGetUniformfv", (uintptr_t)&ret0},
    {"glVertexAttrib1f", (uintptr_t)&glVertexAttrib1f},
    {"glVertexAttrib1fv", (uintptr_t)&glVertexAttrib1fv},
    {"glVertexAttrib2f", (uintptr_t)&glVertexAttrib2f},
    {"glVertexAttrib2fv", (uintptr_t)&glVertexAttrib2fv},
    {"glVertexAttrib3f", (uintptr_t)&glVertexAttrib3f},
    {"glVertexAttrib3fv", (uintptr_t)&glVertexAttrib3fv},
    {"glVertexAttrib4f", (uintptr_t)&glVertexAttrib4f},
    {"glVertexAttrib4fv", (uintptr_t)&glVertexAttrib4fv},
    {"eglReleaseThread", (uintptr_t)&ret0},
    {"glGetAttachedShaders", (uintptr_t)&glGetAttachedShaders},
    {"glGetVertexAttribiv", (uintptr_t)&glGetVertexAttribiv},
    {"glUniform2i", (uintptr_t)&glUniform2i},
    {"glIsRenderbuffer", (uintptr_t)&glIsRenderbuffer},
    {"glGetVertexAttribPointerv", (uintptr_t)&glGetVertexAttribPointerv},
    {"glIsFramebuffer", (uintptr_t)&glIsFramebuffer},
    {"glGetFramebufferAttachmentParameteriv", (uintptr_t)&glGetFramebufferAttachmentParameteriv},
    {"glGetVertexAttribfv", (uintptr_t)&glGetVertexAttribfv},
    {"glGetShaderPrecisionFormat", (uintptr_t)&ret0},
    {"glGetUniformiv", (uintptr_t)&ret0},
    {"glIsProgram", (uintptr_t)&glIsProgram},
    {"glIsShader", (uintptr_t)&ret0},
    {"glIsTexture", (uintptr_t)&glIsTexture},
    {"glReleaseShaderCompiler", (uintptr_t)&glReleaseShaderCompiler},
    {"glShaderBinary", (uintptr_t)&glShaderBinary},
    {"glUniform3i", (uintptr_t)&glUniform3i},
    {"glUniform4i", (uintptr_t)&glUniform4i},

    // Pthread
    {"__pthread_cleanup_push", (uintptr_t)&ret0},
    {"__pthread_cleanup_pop", (uintptr_t)&ret0},

    {"pthread_attr_destroy", (uintptr_t)&pthread_attr_destroy_soloader},
    {"pthread_attr_init", (uintptr_t)&pthread_attr_init_soloader},
    {"pthread_attr_setdetachstate", (uintptr_t)&pthread_attr_setdetachstate_soloader},
    {"pthread_attr_setstacksize", (uintptr_t)&pthread_attr_setstacksize_soloader},
    {"pthread_attr_setschedparam", (uintptr_t)&ret0},

    {"pthread_cond_broadcast", (uintptr_t)&pthread_cond_broadcast_soloader},
    {"pthread_cond_destroy", (uintptr_t)&pthread_cond_destroy_soloader},
    {"pthread_cond_init", (uintptr_t)&pthread_cond_init_soloader},
    {"pthread_cond_signal", (uintptr_t)&pthread_cond_signal_soloader},
    {"pthread_cond_timedwait", (uintptr_t)&pthread_cond_timedwait_soloader},
    {"pthread_cond_wait", (uintptr_t)&pthread_cond_wait_soloader},

    {"pthread_create", (uintptr_t)&pthread_create_soloader},
    {"pthread_detach", (uintptr_t)&pthread_detach_soloader},
    {"pthread_equal", (uintptr_t)&pthread_equal_soloader},
    {"pthread_exit", (uintptr_t)&pthread_exit},
    {"pthread_getschedparam", (uintptr_t)&pthread_getschedparam_soloader},
    {"pthread_getspecific", (uintptr_t)&pthread_getspecific_soloader},
    {"pthread_join", (uintptr_t)&pthread_join_soloader},
    {"pthread_key_create", (uintptr_t)&pthread_key_create},
    {"pthread_key_delete", (uintptr_t)&pthread_key_delete},
    {"pthread_kill", (uintptr_t)&pthread_kill_soloader},

    {"pthread_mutex_destroy", (uintptr_t)&pthread_mutex_destroy_soloader},
    {"pthread_mutex_init", (uintptr_t)&pthread_mutex_init_soloader},
    {"pthread_mutex_lock", (uintptr_t)&pthread_mutex_lock_soloader},
    {"pthread_mutex_trylock", (uintptr_t)&pthread_mutex_trylock_soloader},
    {"pthread_mutex_unlock", (uintptr_t)&pthread_mutex_unlock_soloader},
    {"pthread_mutexattr_destroy", (uintptr_t)&pthread_mutexattr_destroy_soloader},
    {"pthread_mutexattr_init", (uintptr_t)&pthread_mutexattr_init_soloader},
    {"pthread_mutexattr_settype", (uintptr_t)&pthread_mutexattr_settype_soloader},
    {"pthread_mutexattr_setpshared", (uintptr_t)&ret0},
    {"pthread_once", (uintptr_t)&pthread_once_soloader},

    {"pthread_self", (uintptr_t)&pthread_self_soloader},
    {"pthread_setname_np", (uintptr_t)&pthread_setname_np_soloader},
    {"pthread_setschedparam", (uintptr_t)&pthread_setschedparam_soloader},
    {"pthread_setspecific", (uintptr_t)&pthread_setspecific},
    {"pthread_sigmask", (uintptr_t)&ret0},

    {"sem_destroy", (uintptr_t)&sem_destroy_soloader},
    {"sem_getvalue", (uintptr_t)&sem_getvalue_soloader},
    {"sem_init", (uintptr_t)&sem_init_soloader},
    {"sem_post", (uintptr_t)&sem_post_soloader},
    {"sem_timedwait", (uintptr_t)&sem_timedwait_soloader},
    {"sem_trywait", (uintptr_t)&sem_trywait_soloader},
    {"sem_wait", (uintptr_t)&sem_wait_soloader},

    {"sched_get_priority_max", (uintptr_t)&sched_get_priority_max},
    {"sched_get_priority_min", (uintptr_t)&sched_get_priority_min},
    {"sched_yield", (uintptr_t)&sched_yield},

    // wchar, wctype
    {"btowc", (uintptr_t)&btowc},
    {"iswalpha", (uintptr_t)&iswalpha},
    {"iswcntrl", (uintptr_t)&iswcntrl},
    {"iswctype", (uintptr_t)&iswctype},
    {"iswdigit", (uintptr_t)&iswdigit},
    {"iswdigit", (uintptr_t)&iswdigit},
    {"iswlower", (uintptr_t)&iswlower},
    {"iswprint", (uintptr_t)&iswprint},
    {"iswpunct", (uintptr_t)&iswpunct},
    {"iswspace", (uintptr_t)&iswspace},
    {"iswupper", (uintptr_t)&iswupper},
    {"iswxdigit", (uintptr_t)&iswxdigit},
    {"mbrlen", (uintptr_t)&mbrlen},
    {"mbrtowc", (uintptr_t)&mbrtowc},
    {"towlower", (uintptr_t)&towlower},
    {"towupper", (uintptr_t)&towupper},
    {"wcrtomb", (uintptr_t)&wcrtomb},
    {"wcscasecmp", (uintptr_t)&wcscasecmp},
    {"wcscmp", (uintptr_t)&wcscmp},
    {"wcscoll", (uintptr_t)&wcscoll},
    {"wcscpy", (uintptr_t)&wcscpy},
    {"wcsftime", (uintptr_t)&wcsftime},
    {"wcslcat", (uintptr_t)&wcslcat},
    {"wcslcpy", (uintptr_t)&wcslcpy},
    {"wcslen", (uintptr_t)&wcslen},
    {"wcsncasecmp", (uintptr_t)&wcsncasecmp},
    {"wcsncpy", (uintptr_t)&wcsncpy},
    {"wcstombs", (uintptr_t)&wcstombs},
    {"wcsxfrm", (uintptr_t)&wcsxfrm},
    {"wctob", (uintptr_t)&wctob},
    {"wctype", (uintptr_t)&wctype},
    {"wmemchr", (uintptr_t)&wmemchr},
    {"wmemcmp", (uintptr_t)&wmemcmp},
    {"wmemcpy", (uintptr_t)&wmemcpy},
    {"wmemmove", (uintptr_t)&wmemmove},
    {"wmemset", (uintptr_t)&wmemset},

    // libdl
    {"dlclose", (uintptr_t)&ret0},
    {"dlerror", (uintptr_t)&ret0},
    {"dlopen", (uintptr_t)&dlopen_soloader},
    {"dlsym", (uintptr_t)&dlsym_soloader},

    // Errno
    {"__errno", (uintptr_t)&__errno_soloader},
    {"strerror", (uintptr_t)&strerror_soloader},
    {"strerror_r", (uintptr_t)&strerror_r_soloader},

    // Strings
    {"memchr", (uintptr_t)&memchr},
    {"memrchr", (uintptr_t)&memrchr},
    {"strcasecmp", (uintptr_t)&strcasecmp},
    {"strcat", (uintptr_t)&strcat},
    {"strchr", (uintptr_t)&strchr},
    {"strcmp", (uintptr_t)&strcmp},
    {"strcoll", (uintptr_t)&strcoll},
    {"strcpy", (uintptr_t)&strcpy},
    {"strcspn", (uintptr_t)&strcspn},
    {"strdup", (uintptr_t)&strdup},
    {"strlcat", (uintptr_t)&strlcat},
    {"strlcpy", (uintptr_t)&strlcpy},
    {"strlen", (uintptr_t)&strlen},
    {"strncasecmp", (uintptr_t)&strncasecmp},
    {"strncat", (uintptr_t)&strncat},
    {"strncmp", (uintptr_t)&strncmp},
    {"strncpy", (uintptr_t)&strncpy},
    {"strnlen", (uintptr_t)&strnlen},
    {"strpbrk", (uintptr_t)&strpbrk},
    {"strrchr", (uintptr_t)&strrchr},
    {"strspn", (uintptr_t)&strspn},
    {"strstr", (uintptr_t)&strstr},
    {"strtok", (uintptr_t)&strtok},
    {"strtok_r", (uintptr_t)&strtok_r},
    {"strxfrm", (uintptr_t)&strxfrm},

    // Syscalls
    {"fork", (uintptr_t)&fork},
    {"getpagesize", (uintptr_t)&getpagesize},
    {"getpid", (uintptr_t)&getpid},
    {"sbrk", (uintptr_t)&sbrk},
    {"syscall", (uintptr_t)&syscall},
    {"sysconf", (uintptr_t)&ret0},
    {"system", (uintptr_t)&system},
    {"waitpid", (uintptr_t)&ret0},

    // Time
    {"clock", (uintptr_t)&clock_soloader},
    {"clock_getres", (uintptr_t)&clock_getres_soloader},
    {"clock_gettime", (uintptr_t)&clock_gettime_soloader},
    {"difftime", (uintptr_t)&difftime},
    {"gettimeofday", (uintptr_t)&gettimeofday},
    {"gmtime", (uintptr_t)&gmtime},
    {"gmtime64", (uintptr_t)&gmtime64},
    {"gmtime_r", (uintptr_t)&gmtime_r},
    {"localtime", (uintptr_t)&localtime},
    {"localtime64", (uintptr_t)&localtime64},
    {"localtime_r", (uintptr_t)&localtime_r},
    {"mktime", (uintptr_t)&mktime},
    {"mktime64", (uintptr_t)&mktime64},
    {"nanosleep", (uintptr_t)&nanosleep},
    {"strftime", (uintptr_t)&strftime},
    {"time", (uintptr_t)&time},
    {"tzset", (uintptr_t)&tzset},

    // Temp
    {"mkstemp", (uintptr_t)&mkstemp},
    {"mktemp", (uintptr_t)&mktemp},
    {"tmpfile", (uintptr_t)&tmpfile},
    {"tmpnam", (uintptr_t)&tmpnam},

    // stdlib
    {"abort", (uintptr_t)&abort_soloader},
    {"atof", (uintptr_t)&atof},
    {"atoi", (uintptr_t)&atoi},
    {"atol", (uintptr_t)&atol},
    {"atoll", (uintptr_t)&atoll},
    {"exit", (uintptr_t)&exit_soloader},
    {"lrand48", (uintptr_t)&lrand48},
    {"prctl", (uintptr_t)&ret0},
    {"sleep", (uintptr_t)&sleep},
    {"srand48", (uintptr_t)&srand48},
    {"strtod", (uintptr_t)&strtod},
    {"strtof", (uintptr_t)&strtof},
    {"strtoimax", (uintptr_t)&strtoimax},
    {"strtol", (uintptr_t)&strtol},
    {"strtold", (uintptr_t)&strtold},
    {"strtoll", (uintptr_t)&strtoll},
    {"strtoul", (uintptr_t)&strtoul},
    {"strtoull", (uintptr_t)&strtoull},
    {"strtoumax", (uintptr_t)&strtoumax},
    {"usleep", (uintptr_t)&usleep},

#ifdef USE_SCELIBC_IO
    {"qsort", (uintptr_t)&sceLibcBridge_qsort},
    {"rand", (uintptr_t)&sceLibcBridge_rand},
    {"srand", (uintptr_t)&sceLibcBridge_srand},
#else
    {"qsort", (uintptr_t)&qsort},
    {"rand", (uintptr_t)&rand},
    {"srand", (uintptr_t)&srand},
#endif

    // Env
    {"getenv", (uintptr_t)&getenv_soloader},
    {"setenv", (uintptr_t)&setenv_soloader},

    // Jmp
    {"setjmp", (uintptr_t)&setjmp0},  // TODO: May have different struct size?
    {"longjmp", (uintptr_t)&longjmp}, // TODO: May have different struct size?

    // Signals
    {"bsd_signal", (uintptr_t)&signal},
    {"raise", (uintptr_t)&raise},
    {"sigaction", (uintptr_t)&sigaction},

    // Locale
    {"setlocale", (uintptr_t)&setlocale},

    // zlib
    // { "adler32", (uintptr_t)&adler32 },
    // { "compress", (uintptr_t)&compress },
    // { "compressBound", (uintptr_t)&compressBound },
    // { "crc32", (uintptr_t)&crc32 },
    // { "deflate", (uintptr_t)&deflate },
    // { "deflateEnd", (uintptr_t)&deflateEnd },
    // { "deflateInit2_", (uintptr_t)&deflateInit2_ },
    // { "deflateInit_", (uintptr_t)&deflateInit_ },
    // { "deflateReset", (uintptr_t)&deflateReset },
    // { "gzclose", (uintptr_t)&gzclose },
    // { "gzgets", (uintptr_t)&gzgets },
    // { "gzopen", (uintptr_t)&gzopen },
    // { "inflate", (uintptr_t)&inflate },
    // { "inflateEnd", (uintptr_t)&inflateEnd },
    // { "inflateInit2_", (uintptr_t)&inflateInit2_ },
    // { "inflateInit_", (uintptr_t)&inflateInit_ },
    // { "inflateReset", (uintptr_t)&inflateReset },
    // { "uncompress", (uintptr_t)&uncompress },

    {"symlink", (uintptr_t)&ret0},
    {"systemTime", (uintptr_t)&ret0},
    {"jniRegisterNativeMethods", (uintptr_t)&jniRegisterNativeMethods},
    {"epoll_create", (uintptr_t)&ret0},

    {"_ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tji20audio_output_flags_tPFviPvS4_ES4_iRKNS_2spINS_7IMemoryEEEbi", (uintptr_t)&libmedia},
    {"_ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tii20audio_output_flags_tPFviPvS4_ES4_iRKNS_2spINS_7IMemoryEEEbi", (uintptr_t)&libmedia},
    {"_ZN7android10AudioTrack3setEijiiijPFviPvS1_ES1_iRKNS_2spINS_7IMemoryEEEbi", (uintptr_t)&libmedia},
    {"_ZN7android10AudioTrack3setEijiiijPFviPvS1_ES1_iRKNS_2spINS_7IMemoryEEEb", (uintptr_t)&libmedia},
    {"_ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tji20audio_output_flags_tPFviPvS4_ES4_iRKNS_2spINS_7IMemoryEEEbiNS0_13transfer_typeEPK20audio_offload_info_t", (uintptr_t)&libmedia},
    {"_ZN7android10AudioTrack3setE19audio_stream_type_tj14audio_format_tji20audio_output_flags_tPFviPvS4_ES4_iRKNS_2spINS_7IMemoryEEEbiNS0_13transfer_typeEPK20audio_offload_info_ti", (uintptr_t)&libmedia},
    {"_ZNK7android10AudioTrack9initCheckEv", (uintptr_t)&libmedia},
    {"_ZN7android10AudioTrack5startEv", (uintptr_t)&libmedia},
    {"_ZN7android11AudioRecord3setE14audio_source_tj14audio_format_tjiNS0_12record_flagsEPFviPvS4_ES4_ibi", (uintptr_t)&libmedia},
    {"_ZN7android11AudioRecord3setEijijijPFviPvS1_ES1_ibi", (uintptr_t)&libmedia},
    {"_ZN7android11AudioRecord3setEijijijPFviPvS1_ES1_ib", (uintptr_t)&libmedia},
    {"_ZN7android11AudioRecord5startEv", (uintptr_t)&libmedia},
    {"_ZN7android11AudioRecord3setE14audio_source_tj14audio_format_tjiPFviPvS3_ES3_ibiNS0_13transfer_typeE19audio_input_flags_t", (uintptr_t)&libmedia},

    {"_ZNK7android9ZipFileRO12getEntryInfoEPvPiPlS3_S3_S3_S3_", (uintptr_t)&libutils},
    {"_ZNK7android9ZipFileRO12getEntryInfoEPvPiPjS3_PlS4_S4_", (uintptr_t)&libutils},
    {"_ZNK7android9ZipFileRO12getEntryInfoEPvPiPjS3_PxPlS5_", (uintptr_t)&libutils},
    {"_ZN7android9ZipFileRO4openEPKc", (uintptr_t)&libutils},
    {"_ZNK7android9ZipFileRO15uncompressEntryEPvS1_", (uintptr_t)&libutils},
    {"_ZNK7android9ZipFileRO15findEntryByNameEPKc", (uintptr_t)&libutils},
};

void resolve_imports(so_module *mod)
{
    __sF_fake[0] = *stdin;
    __sF_fake[1] = *stdout;
    __sF_fake[2] = *stderr;
    default_dynlib_m = default_dynlib;
    size_default_dynlib = sizeof(default_dynlib);
    so_resolve(mod, default_dynlib, size_default_dynlib, 0);
}
